
#if UNITY_EDITOR
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor.Experimental.GraphView;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
using static UnityEditor.Experimental.GraphView.Port;
using Direction = UnityEditor.Experimental.GraphView.Direction;

/// <summary>
/// UI元素工具类，提供创建各种Unity UI元素的便捷方法
/// </summary>
public static class UIElementTools
{
    public static int FontSize = 22;
    /// <summary>
    /// 创建文本输入框
    /// </summary>
    /// <param name="label">输入框标签</param>
    /// <param name="onValueChange">值变化回调</param>
    /// <returns>创建的TextField对象</returns>
    public static TextField CreateTextField(string label, EventCallback<string> onValueChange = null)
    {
        TextField textField = new TextField()
        {
            value = label,
            style =
            {
                flexGrow = 1,
                flexShrink = 1,
                minWidth = 200,
                color = Color.white,
                fontSize = FontSize
            }
        };
        if (onValueChange != null)
        {
            textField.RegisterCallback<FocusOutEvent>(evt =>
            {
                onValueChange(textField.value);
            });
        }
        return textField;
    }
    /// <summary>
    /// 创建多行文本输入框
    /// </summary>
    /// <param name="label">输入框标签</param>
    /// <param name="onValueChange">值变化回调</param>
    /// <returns>创建的TextArea对象</returns>
    public static TextField CreateTextArea(string label, EventCallback<string> onValueChange = null)
    {
        TextField textField = CreateTextField(label, onValueChange);
        textField.multiline = true;
        return textField;
    }

    /// <summary>
    /// 创建浮点数滑动条
    /// </summary>
    /// <param name="min">最小值</param>
    /// <param name="max">最大值</param>
    /// <param name="value">初始值</param>
    /// <param name="onValueChange">值变化回调</param>
    /// <returns>创建的Slider对象</returns>
    public static Slider CreateSlider(float min, float max, float value, EventCallback<ChangeEvent<float>> onValueChange = null)
    {
        Slider slider = new Slider(min, max)
        {
            value = value
        };
        if (onValueChange != null)
        {
            slider.RegisterValueChangedCallback(onValueChange);
        }
        return slider;
    }

    /// <summary>
    /// 创建按钮
    /// </summary>
    /// <param name="text">按钮文本</param>
    /// <param name="onClick">点击回调</param>
    /// <returns>创建的Button对象</returns>
    public static Button CreateButton(string text, Action onClick = null)
    {
        Button button = new Button()
        {
            text = text
        };
        if (onClick != null)
        {
            button.clicked += onClick;
        }
        return button;
    }

    /// <summary>
    /// 创建列表视图
    /// </summary>
    /// <typeparam name="T">列表项类型</typeparam>
    /// <param name="items">数据列表</param>
    /// <param name="itemHeight">每项高度</param>
    /// <param name="makeItem">创建列表项回调</param>
    /// <param name="bindItem">绑定数据回调</param>
    /// <returns>创建的ListView对象</returns>
    public static ListView CreateListView<T>(IList items, int itemHeight,
        Func<VisualElement> makeItem, Action<VisualElement, int> bindItem)
    {
        return new ListView(items, itemHeight, makeItem, bindItem);
    }

    /// <summary>
    /// 创建开关控件
    /// </summary>
    /// <param name="label">开关标签</param>
    /// <param name="value">初始状态</param>
    /// <param name="onValueChange">状态变化回调</param>
    /// <returns>创建的Toggle对象</returns>
    public static Toggle CreateToggle(string label, bool value, EventCallback<ChangeEvent<bool>> onValueChange = null)
    {
        Toggle toggle = new Toggle(label)
        {
            value = value
        };
        if (onValueChange != null)
        {
            toggle.RegisterValueChangedCallback(onValueChange);
        }
        return toggle;
    }

    /// <summary>
    /// 创建可折叠区域
    /// </summary>
    /// <param name="title">标题文本</param>
    /// <param name="value">初始展开状态</param>
    /// <returns>创建的Foldout对象</returns>
    public static Foldout CreateFoldout(string title, bool value = false)
    {
        return new Foldout()
        {
            text = title,
            value = value
        };
    }

    /// <summary>
    /// 创建文本标签
    /// </summary>
    /// <param name="text">标签文本</param>
    /// <returns>创建的Label对象</returns>
    public static Label CreateLabel(string text, Color color = default)
    {
        var label = new Label(text);
        label.style.fontSize = FontSize;
        label.style.color = color;
        return label;
    }

    /// <summary>
    /// 创建枚举选择字段
    /// </summary>
    /// <param name="defaultValue">默认枚举值</param>
    /// <param name="onValueChange">值变化回调</param>
    /// <returns>创建的EnumField对象</returns>
    public static EnumField CreateEnumField(Enum defaultValue, EventCallback<ChangeEvent<Enum>> onValueChange = null)
    {
        EnumField enumField = new EnumField(defaultValue);
        if (onValueChange != null)
        {
            enumField.RegisterValueChangedCallback(onValueChange);
        }
        return enumField;
    }

    /// <summary>
    /// 创建整数字段
    /// </summary>
    /// <param name="value">初始值</param>
    /// <param name="onValueChange">值变化回调</param>
    /// <returns>创建的IntegerField对象</returns>
    public static IntegerField CreateIntegerField(string name, int value, EventCallback<ChangeEvent<int>> onValueChange = null)
    {
        IntegerField intField = new IntegerField(name)
        {
            value = value
        };
        intField.Q<Label>().style.flexBasis = Length.Percent(50);
        intField.Q<Label>().style.fontSize = FontSize;
        intField.Q<Label>().style.color = Color.white;
        intField.Q<Label>().style.unityFontStyleAndWeight = FontStyle.Bold;
        if (onValueChange != null)
        {
            intField.RegisterValueChangedCallback(onValueChange);
        }
        return intField;
    }

    /// <summary>
    /// 创建浮点数字段
    /// </summary>
    /// <param name="value">初始值</param>
    /// <param name="onValueChange">值变化回调</param>
    /// <returns>创建的FloatField对象</returns>
    public static FloatField CreateFloatField(float value, EventCallback<ChangeEvent<float>> onValueChange = null)
    {
        FloatField floatField = new FloatField { value = value };
        if (onValueChange != null)
        {
            floatField.RegisterValueChangedCallback(onValueChange);
        }
        return floatField;
    }

    /// <summary>
    /// 创建单选按钮组
    /// </summary>
    /// <param name="selectedIndex">默认选中索引</param>
    /// <param name="options">选项列表</param>
    /// <param name="onValueChange">值变化回调</param>
    /// <returns>创建的RadioButtonGroup对象</returns>
    public static RadioButtonGroup CreateRadioButtonGroup(int selectedIndex, List<string> options,
        EventCallback<ChangeEvent<int>> onValueChange = null)
    {
        RadioButtonGroup radioGroup = new RadioButtonGroup
        {
            choices = options,
            value = selectedIndex
        };
        if (onValueChange != null)
        {
            radioGroup.RegisterValueChangedCallback(onValueChange);
        }
        return radioGroup;
    }

    /// <summary>
    /// 创建下拉选择框
    /// </summary>
    /// <param name="label">标签文本</param>
    /// <param name="choices">选项列表</param>
    /// <param name="defaultIndex">默认选中索引</param>
    /// <param name="onValueChange">值变化回调</param>
    /// <returns>创建的DropdownField对象</returns>
    public static DropdownField CreateDropdownField(string label, List<string> choices, int defaultIndex = 0,
        EventCallback<ChangeEvent<string>> onValueChange = null)
    {
        DropdownField dropdown = new DropdownField(label, choices, defaultIndex);
        // 设置标签和下拉列表文字大小
        dropdown.style.width = Length.Percent(100);
        dropdown.style.fontSize = FontSize;
        // 设置标签占50%宽度
        dropdown.Q<Label>().style.flexBasis = Length.Percent(50);
        dropdown.Q<Label>().style.fontSize = FontSize;
        dropdown.Q<Label>().style.color = Color.white;
        // 设置下拉菜单占50%宽度
        dropdown.Q(className: "unity-base-popup-field__input").style.flexBasis = Length.Percent(50);
        // 设置粗体字体
        dropdown.style.unityFontStyleAndWeight = FontStyle.Bold;
        dropdown.Q<Label>().style.unityFontStyleAndWeight = FontStyle.Bold;

        if (onValueChange != null)
        {
            dropdown.RegisterValueChangedCallback(onValueChange);
        }
        return dropdown;
    }

    /// <summary>
    /// 创建整数滑动条
    /// </summary>
    /// <param name="min">最小值</param>
    /// <param name="max">最大值</param>
    /// <param name="value">初始值</param>
    /// <param name="onValueChange">值变化回调</param>
    /// <returns>创建的SliderInt对象</returns>
    public static SliderInt CreateSliderInt(int min, int max, int value, EventCallback<ChangeEvent<int>> onValueChange = null)
    {
        SliderInt slider = new SliderInt(min, max)
        {
            value = value
        };
        if (onValueChange != null)
        {
            slider.RegisterValueChangedCallback(onValueChange);
        }
        return slider;
    }

    /// <summary>
    /// 创建技能节点端口
    /// </summary>
    /// <param name="name">端口名称</param>
    /// <param name="direction">端口方向 (Input/Output)</param>
    /// <param name="capacity">端口容量 (Single/Multi)</param>
    /// <param name="portType">端口类型</param>
    /// <returns>创建的Port对象</returns>
    public static Port CreateSkillPort(string name, Direction direction, Capacity capacity, System.Type portType = null)
    {
        var port = Port.Create<Edge>(Orientation.Horizontal, direction, capacity, portType ?? typeof(object));
        port.Q<Label>().style.fontSize = 20;
        port.Q<Label>().style.unityFontStyleAndWeight = FontStyle.Bold;
        port.Q<Label>().style.color = Color.white;
        return port;
    }

    /// <summary>
    /// 创建输入端口
    /// </summary>
    /// <param name="name">端口名称</param>
    /// <param name="capacity">端口容量 (Single/Multi)</param>
    /// <param name="portType">端口类型</param>
    /// <returns>创建的输入Port对象</returns>
    public static Port CreateInputPort(this Node node, string name, Capacity capacity, Type portType, Color color)
    {
        var port = CreateSkillPort(name, Direction.Input, capacity, portType);
        port.portName = name;
        port.portColor = color;
        return port;
    }

    /// <summary>
    /// 创建输出端口
    /// </summary>
    /// <param name="name">端口名称</param>
    /// <param name="capacity">端口容量 (Single/Multi)</param>
    /// <param name="portType">端口类型</param>
    /// <returns>创建的输出Port对象</returns>
    public static Port CreateOutputPort(this Node node, string name, Capacity capacity, Type portType, Color color)
    {
        var port = CreateSkillPort(name, Direction.Output, capacity, portType);
        port.portName = name;
        port.portColor = color;
        return port;
    }

    public static void GetConnectedNodes(this Edge edge,
        out Node sourceNode, out Node targetNode)
    {
        sourceNode = edge.output?.node as Node;  // 来源 Node
        targetNode = edge.input?.node as Node;   // 目标 Node
    }

    /// <summary>
    /// 创建属性字段（标签+输入框）
    /// </summary>
    /// <param name="label">属性名称</param>
    /// <param name="value">初始值</param>
    /// <param name="onValueChange">值变化回调</param>
    /// <returns>创建的VisualElement容器</returns>
    public static VisualElement CreatePropertyField(string label, string value,
        EventCallback<string> onValueChange = null)
    {
        var container = new VisualElement();
        container.style.flexDirection = FlexDirection.Row;
        container.style.alignItems = Align.Center;
        container.style.flexGrow = 1;
        container.style.width = Length.Percent(100);
        container.style.fontSize = FontSize;

        var labelElement = new Label(label)
        {
            style = {
                color = Color.white,
                unityTextAlign = TextAnchor.MiddleLeft,
                flexBasis = Length.Percent(50),
                flexShrink = 0,
                flexGrow = 0,
                minWidth = 100,
                unityFontStyleAndWeight = FontStyle.Bold,
                fontSize = FontSize
            }
        };

        var textField = CreateTextField(value, onValueChange);
        textField.style.flexBasis = Length.Percent(70);



        container.Add(labelElement);
        container.Add(textField);
        return container;
    }

    /// <summary>
    /// 创建Vector2字段
    /// </summary>
    /// <param name="label">属性名称</param>
    /// <param name="x">初始x值</param>
    /// <param name="y">初始y值</param>
    /// <param name="onValueChange">值变化回调</param>
    /// <returns>创建的VisualElement容器</returns>
    /// <summary>
    /// 创建Vector2字段
    /// </summary>
    /// <param name="label">属性名称</param>
    /// <param name="value">初始值</param>
    /// <param name="onValueChange">值变化回调</param>
    /// <returns>创建的VisualElement容器</returns>
    public static VisualElement CreateVector2Field(string label, Vector2 value,
        EventCallback<Vector2> onValueChange = null)
    {
        var container = new VisualElement();
        container.style.flexDirection = FlexDirection.Row;
        container.style.alignItems = Align.Center;
        container.style.flexGrow = 1;
        container.style.width = Length.Percent(100);
        container.style.minWidth = 400;

        var labelElement = new Label(label)
        {
            style = {
                color = Color.white,
                unityTextAlign = TextAnchor.MiddleLeft,
                flexBasis = Length.Percent(40),
                flexShrink = 0,
                minWidth = 120,
                unityFontStyleAndWeight = FontStyle.Bold,
                fontSize = FontSize
            }
        };

        var xField = CreateFloatField(value.x, evt =>
        {
            if (onValueChange != null)
            {
                value.x = evt.newValue;
                onValueChange(value);
            }
        });
        xField.style.minWidth = 100;
        xField.style.flexGrow = 1;
        xField.style.flexBasis = Length.Percent(30);

        var yField = CreateFloatField(value.y, evt =>
        {
            if (onValueChange != null)
            {
                value.y = evt.newValue;
                onValueChange(value);
            }
        });
        yField.style.minWidth = 100;
        yField.style.flexGrow = 1;
        yField.style.flexBasis = Length.Percent(30);

        container.Add(labelElement);
        container.Add(xField);
        container.Add(yField);
        return container;
    }

    /// <summary>
    /// 创建布尔属性字段（标签+开关）
    /// </summary>
    /// <param name="label">属性名称</param>
    /// <param name="value">初始值</param>
    /// <param name="onValueChange">值变化回调</param>
    /// <returns>创建的VisualElement容器</returns>
    public static VisualElement CreateBoolField(string label, bool value,
        EventCallback<ChangeEvent<bool>> onValueChange = null)
    {
        var container = new VisualElement();
        container.style.flexDirection = FlexDirection.Row;
        container.style.alignItems = Align.Center;
        container.style.flexGrow = 1;
        container.style.width = Length.Percent(100);

        var labelElement = new Label(label)
        {
            style = {
                unityTextAlign = TextAnchor.MiddleLeft,
                flexShrink = 0,
                minWidth = 150,
                fontSize = FontSize,
                unityFontStyleAndWeight = FontStyle.Bold,
            }
        };

        var toggle = CreateToggle("", value, onValueChange);
        toggle.style.marginLeft = 5;
        toggle.style.flexBasis = Length.Percent(70);
        toggle.style.justifyContent = Justify.FlexEnd;
        toggle.style.alignItems = Align.Center;
        toggle.style.marginRight = 20;

        container.Add(labelElement);
        container.Add(toggle);
        return container;
    }

    /// <summary>
    /// 创建位运算枚举下拉列表(Flags)
    /// </summary>
    /// <typeparam name="T">枚举类型</typeparam>
    /// <param name="label">标签文本</param>
    /// <param name="value">初始值</param>
    /// <param name="onValueChange">值变化回调</param>
    /// <returns>创建的VisualElement容器</returns>
    public static VisualElement CreateFlagsEnumField<T>(string label, T value,
        Action<T> onValueChange = null) where T : Enum
    {
        var container = new VisualElement();
        var flagsField = new EnumFlagsField(label, value)
        {
            style =
            {
                color = Color.white,
                unityTextAlign = TextAnchor.MiddleLeft,
                flexBasis = Length.Percent(50),
                flexShrink = 0,
                flexGrow = 1,
                minWidth = 200,
                fontSize = FontSize
            }
        };
        flagsField.Q<Label>().style.fontSize = FontSize;

        if (onValueChange != null)
        {
            flagsField.RegisterValueChangedCallback(evt =>
            {
                if (evt.newValue is T newValue)
                {
                    onValueChange(newValue);
                }
            });
        }
        container.Add(flagsField);
        return container;
    }
}
#endif